<template>
	<view class="map-container">
		<!-- 地图可移动区域 -->
		<movable-area class="map-area">
			<movable-view
				class="map-view"
				:x="mapPosition.x"
				:y="mapPosition.y"
				direction="all"
				@change="handleMapMove"
				:style="mapViewStyle"
			>
				<!-- 缩放容器 (使用CSS transform实现缩放) -->
				<view class="map-scale-wrapper" :style="mapScaleWrapperStyle">
					<!-- 静态地图图片 -->
					<image
						class="map-image"
						:src="mapImageSrc"
						mode="scaleToFill"
						@load="handleImageLoad"
						@touchstart="handleTouchStart"
						@touchmove="handleTouchMove"
						@touchend="handleTouchEnd"
						@touchcancel="handleTouchCancel"
					/>

					<!-- 地点标记点 -->
					<view
						v-for="location in locations"
						:key="location.id"
						class="map-marker"
						:style="getMarkerStyle(location)"
						@tap.stop="handleMarkerTap(location)"
					>
						<view class="marker-pin">
							<image class="marker-icon" src="/static/location.png" mode="aspectFit" />
						</view>
						<view v-if="location.avgRating > 0" class="marker-badge">
							{{ location.avgRating }}
						</view>
						<!-- 地点名称标签 -->
						<view class="marker-label">{{ location.name }}</view>
					</view>

					<!-- 临时标记点（长按预览） -->
					<view
						v-if="tempMarker"
						class="map-marker temp-marker"
						:style="getTempMarkerStyle()"
					>
						<view class="marker-pin temp-pin">
							<image class="marker-icon" src="/static/location.png" mode="aspectFit" />
						</view>
						<view class="temp-label">预览位置</view>
					</view>
				</view>
			</movable-view>
		</movable-area>

		<!-- 控制按钮 -->
		<view class="controls">
			<!-- 缩放控制 -->
			<view class="zoom-controls">
				<view class="control-btn" @tap="zoomIn">
					<text class="control-icon">+</text>
				</view>
				<view class="control-btn" @tap="zoomOut">
					<text class="control-icon">−</text>
				</view>
				<view class="control-btn" @tap="resetView">
					<text class="control-icon">⟲</text>
				</view>
			</view>

			<!-- 我的位置按钮 (可选功能) -->
			<view class="my-location-btn" @tap="goToMyLocation">
				<text class="control-icon">⊙</text>
			</view>
		</view>

		<!-- 加载提示 -->
		<view v-if="isLoading" class="loading-overlay">
			<view class="loading-content">
				<view class="loading-spinner"></view>
				<text class="loading-text">加载中...</text>
			</view>
		</view>

		<!-- 信息窗口 (半屏抽屉) -->
		<view
			v-if="selectedLocation"
			class="info-window"
			:class="{ 'show': showInfoWindow }"
		>
			<view class="info-header">
				<text class="info-title">{{ selectedLocation.name }}</text>
				<view class="info-close" @tap="closeInfoWindow">
					<text>✕</text>
				</view>
			</view>

			<view class="info-body">
				<!-- 评分信息 -->
				<view class="info-rating">
					<text class="rating-value">{{ selectedLocation.avgRating || '暂无' }}</text>
					<text class="rating-label">平均评分</text>
					<text class="rating-count">({{ selectedLocation.ratingsCount || 0 }}人评价)</text>
				</view>

				<!-- 操作按钮 -->
				<view class="info-actions">
					<button class="action-btn primary" @tap="goToDetail">
						查看详情
					</button>
					<button class="action-btn secondary" @tap="handleRate">
						我要评分
					</button>
				</view>
			</view>
		</view>

		<!-- 添加地点弹窗 -->
		<view v-if="showAddLocationForm" class="modal-overlay" @tap="closeAddLocationForm">
			<view class="modal-content" @tap.stop>
				<view class="modal-header">
					<text class="modal-title">添加新地点</text>
					<view class="modal-close" @tap="closeAddLocationForm">
						<text>✕</text>
					</view>
				</view>

				<view class="form-body">
					<view class="form-item">
						<text class="form-label">地点名称 *</text>
						<input
							class="form-input"
							v-model="addLocationForm.name"
							placeholder="请输入地点名称"
							maxlength="50"
						/>
					</view>

					<view class="form-item">
						<text class="form-label">坐标位置</text>
						<text class="coordinate-text">
							X: {{ addLocationForm.coordinateX }}, Y: {{ addLocationForm.coordinateY }}
						</text>
						<text class="coordinate-hint">坐标已自动填充</text>
					</view>

					<button
						class="submit-btn"
						:disabled="!addLocationForm.name || isSubmitting"
						@tap="submitNewLocation"
					>
						{{ isSubmitting ? '提交中...' : '提交审核' }}
					</button>

					<view class="form-hint">
						<text class="hint-icon">ℹ️</text>
						<text class="hint-text">提交后需要管理员审核通过才会显示在地图上</text>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
import { locationAPI, utils } from '@/utils/api.js'
import CoordinateTransform from '@/utils/coordinateTransform.js'

// 地图资源配置 - 从服务器加载以减小小程序包体积
const MAP_IMAGE_SRC = 'https://xinyadelicacies.com/uploads/map.png'
const MAP_IMAGE_WIDTH = 4370
const MAP_IMAGE_HEIGHT = 6142
const ZOOM_STEP_FACTOR = 1.2
const SCALE_DECIMAL_PRECISION = 3
const LONG_PRESS_DURATION = 500 // 长按时长（毫秒）

export default {
	data() {
		return {
			// 地图状态
			mapImageSrc: MAP_IMAGE_SRC,
			mapScale: 1.0,
			mapPosition: {
				x: 0,
				y: 0
			},
			mapImageSize: {
				width: 0,
				height: 0
			},
			viewportSize: {
				width: 0,
				height: 0
			},
			initialScale: 1.0,
			minScale: 0.5,
			maxScale: 3.0,
			coordinateScaleFactor: 1,

			// 坐标转换实例
			coordinateTransform: null,

			// 地点数据
			locations: [],
			selectedLocation: null,
			showInfoWindow: false,

			// 添加地点表单
			showAddLocationForm: false,
			longPressPosition: { x: 0, y: 0 },
			addLocationForm: {
				name: '',
				coordinateX: 0,
				coordinateY: 0
			},

			// 临时标记点（长按时显示，用于预览位置）
			tempMarker: null,

			// 长按检测
			touchStartTime: 0,
			touchStartPosition: { x: 0, y: 0 },
			longPressTimer: null,
			isLongPressing: false,

			// UI状态
			isLoading: false,
			isSubmitting: false
		}
	},

	computed: {
		mapViewStyle() {
			if (!this.mapImageSize.width || !this.mapImageSize.height) {
				return {}
			}

			// 使用缩放后的尺寸，而不是原始尺寸
			// 这样 movable-view 的布局尺寸会和实际显示的内容匹配
			const displaySize = this.getDisplaySize()
			return {
				width: `${displaySize.width}px`,
				height: `${displaySize.height}px`
			}
		},

		mapScaleWrapperStyle() {
			// map-scale-wrapper 保持原始尺寸，通过 transform: scale() 缩放
			// 虽然布局尺寸会超出 movable-view，但显示尺寸是正确的
			const style = {
				transform: `scale(${this.mapScale})`,
				transformOrigin: 'top left'
			}

			if (this.mapImageSize.width && this.mapImageSize.height) {
				style.width = `${this.mapImageSize.width}px`
				style.height = `${this.mapImageSize.height}px`
			}

			return style
		}
	},

	onLoad() {
		// 页面加载时获取地点数据
		this.initializeViewport()
		this.initializeMapDimensions()
		this.initializeCoordinateTransform()
		this.loadLocations()

		// 确保坐标转换实例使用最新的 mapScale 和 mapPosition
		// 因为 initializeMapDimensions() 可能会修改这些值
		this.$nextTick(() => {
			this.updateCoordinateTransform()
			console.log('初始化完成，坐标转换实例已更新:', this.coordinateTransform?.getMatrix())
		})
	},

	methods: {
		/**
		 * 初始化坐标转换实例
		 */
		initializeCoordinateTransform() {
			this.coordinateTransform = new CoordinateTransform({
				scale: this.mapScale,
				offsetX: this.mapPosition.x,
				offsetY: this.mapPosition.y
			})
		},

		/**
		 * 更新坐标转换实例
		 */
		updateCoordinateTransform() {
			if (this.coordinateTransform) {
				this.coordinateTransform.update({
					scale: this.mapScale,
					offsetX: this.mapPosition.x,
					offsetY: this.mapPosition.y
				})
			}
		},

		initializeViewport() {
			try {
				const { windowWidth, windowHeight } = uni.getSystemInfoSync()
				this.viewportSize = {
					width: windowWidth,
					height: windowHeight
				}
			} catch (error) {
				console.warn('获取系统信息失败:', error)
			}
		},

		initializeMapDimensions() {
			if (!MAP_IMAGE_WIDTH || !MAP_IMAGE_HEIGHT) return

			this.mapImageSize = {
				width: MAP_IMAGE_WIDTH,
				height: MAP_IMAGE_HEIGHT
			}

			this.updateScaleBounds()
		},

		updateScaleBounds() {
			if (!this.viewportSize.width || !this.mapImageSize.width) return

			const scaleToFitWidth = this.viewportSize.width / this.mapImageSize.width
			const scaleToFitHeight = this.viewportSize.height / this.mapImageSize.height
			const initialScale = Math.min(scaleToFitWidth, scaleToFitHeight)
			const formattedInitial = Number(initialScale.toFixed(SCALE_DECIMAL_PRECISION)) || this.initialScale
			this.initialScale = formattedInitial
			this.minScale = Number(Math.max(formattedInitial * 0.5, 0.02).toFixed(SCALE_DECIMAL_PRECISION))
			this.maxScale = Number(Math.max(formattedInitial * 6, formattedInitial).toFixed(SCALE_DECIMAL_PRECISION))
			this.mapScale = this.initialScale
			if (this.viewportSize.width > 0) {
				const factor = this.mapImageSize.width / this.viewportSize.width
				this.coordinateScaleFactor = Number(factor.toFixed(6)) || 1
			}
			this.resetMapPosition()

			// 确保坐标转换实例已经初始化并且使用最新的参数
			// 即使 resetMapPosition() 中已经调用了一次，这里再调用一次确保万无一失
			this.updateCoordinateTransform()
		},

		getDisplaySize(scale = this.mapScale) {
			return {
				width: this.mapImageSize.width * scale,
				height: this.mapImageSize.height * scale
			}
		},

		setMapScale(nextScale) {
			if (!this.mapImageSize.width) return

			const clamped = Math.min(this.maxScale, Math.max(this.minScale, nextScale))
			const roundedCurrent = Number(this.mapScale.toFixed(SCALE_DECIMAL_PRECISION))
			const roundedTarget = Number(clamped.toFixed(SCALE_DECIMAL_PRECISION))

			if (roundedCurrent === roundedTarget) {
				return
			}

			const previousSize = this.getDisplaySize()
			const nextSize = this.getDisplaySize(roundedTarget)
			const deltaX = (previousSize.width - nextSize.width) / 2
			const deltaY = (previousSize.height - nextSize.height) / 2

			this.mapPosition = {
				x: Number((this.mapPosition.x + deltaX).toFixed(1)),
				y: Number((this.mapPosition.y + deltaY).toFixed(1))
			}

			this.mapScale = roundedTarget

			// 更新坐标转换实例
			this.updateCoordinateTransform()
		},

		resetMapPosition() {
			if (!this.viewportSize.width || !this.mapImageSize.width) return

			const { width, height } = this.getDisplaySize()
			const offsetX = (this.viewportSize.width - width) / 2
			const offsetY = (this.viewportSize.height - height) / 2

			this.mapPosition = {
				x: Number(offsetX.toFixed(1)),
				y: Number(offsetY.toFixed(1))
			}

			// 更新坐标转换实例
			this.updateCoordinateTransform()
		},

		/**
		 * 加载地点列表
		 */
		async loadLocations() {
			this.isLoading = true
			try {
				const response = await locationAPI.getLocations({
					status: 'APPROVED',
					page: 1,
					limit: 100 // 获取所有已审核的地点
				})

				if (response.success) {
					this.locations = response.data
					console.log('加载地点数据成功:', this.locations.length, '个地点')
				}
			} catch (error) {
				console.error('加载地点失败:', error)
				utils.handleError(error, '加载地点数据失败')
			} finally {
				this.isLoading = false
			}
		},

		/**
		 * 地图图片加载完成
		 * 总是使用真实的图片尺寸以确保坐标计算准确
		 */
		handleImageLoad(e) {
			console.log('地图图片加载完成:', e.detail)

			// 总是更新图片尺寸为真实加载的尺寸
			if (e && e.detail && e.detail.width && e.detail.height) {
				const actualWidth = e.detail.width
				const actualHeight = e.detail.height

				console.log('图片实际尺寸:', {
					actual: { width: actualWidth, height: actualHeight },
					expected: { width: MAP_IMAGE_WIDTH, height: MAP_IMAGE_HEIGHT },
					match: actualWidth === MAP_IMAGE_WIDTH && actualHeight === MAP_IMAGE_HEIGHT
				})

				this.mapImageSize = {
					width: actualWidth,
					height: actualHeight
				}
				this.updateScaleBounds()

				// 在图片加载完成后更新坐标转换实例
				this.$nextTick(() => {
					this.updateCoordinateTransform()
				})
			}
		},

		/**
		 * 地图移动事件
		 */
		handleMapMove(e) {
			this.mapPosition = {
				x: e.detail.x,
				y: e.detail.y
			}

			// 更新坐标转换实例
			this.updateCoordinateTransform()
		},

		/**
		 * 计算标记点样式
		 * @param {Object} location 地点数据
		 */
		getMarkerStyle(location) {
			// 使用原始地图像素坐标进行渲染，避免因设备/屏幕造成的缩放误差
			const rawX = Number(location.coordinateX) || 0
			const rawY = Number(location.coordinateY) || 0
			const x = rawX
			const y = rawY

			return {
				left: `${x}px`,
				top: `${y}px`,
				transform: `scale(${1 / this.mapScale})` // 保持标记大小不随地图缩放
			}
		},

		/**
		 * 计算临时标记点样式
		 */
		getTempMarkerStyle() {
			if (!this.tempMarker) return {}

			const x = Number(this.tempMarker.coordinateX) || 0
			const y = Number(this.tempMarker.coordinateY) || 0

			return {
				left: `${x}px`,
				top: `${y}px`,
				transform: `scale(${1 / this.mapScale})` // 保持标记大小不随地图缩放
			}
		},

		/**
		 * 点击标记点
		 */
		handleMarkerTap(location) {
			console.log('点击标记:', location.name)
			this.selectedLocation = location
			this.showInfoWindow = true
		},

		/**
		 * 关闭信息窗口
		 */
		closeInfoWindow() {
			this.showInfoWindow = false
			setTimeout(() => {
				this.selectedLocation = null
			}, 300) // 等待动画结束
		},

		/**
		 * 前往详情页
		 */
		goToDetail() {
			if (!this.selectedLocation) return

			uni.navigateTo({
				url: `/pages/location-detail/location-detail?id=${this.selectedLocation.id}`
			})
		},

		/**
		 * 评分功能
		 */
		handleRate() {
			// 检查登录状态
			const token = uni.getStorageSync('token')
			if (!token) {
				uni.showModal({
					title: '提示',
					content: '请先登录后再进行评分',
					confirmText: '去登录',
					success: (res) => {
						if (res.confirm) {
							uni.navigateTo({
								url: '/pages/login/login'
							})
						}
					}
				})
				return
			}

			// 跳转到详情页进行评分
			this.goToDetail()
		},

		/**
		 * 放大
		 */
		zoomIn() {
			this.setMapScale(this.mapScale * ZOOM_STEP_FACTOR)
			console.log('放大地图到:', this.mapScale)
		},

		/**
		 * 缩小
		 */
		zoomOut() {
			this.setMapScale(this.mapScale / ZOOM_STEP_FACTOR)
			console.log('缩小地图到:', this.mapScale)
		},

		/**
		 * 重置视图
		 */
		resetView() {
			this.setMapScale(this.initialScale)
			this.resetMapPosition()
			console.log('重置地图视图')
		},

		/**
		 * 定位到我的位置 (示例功能)
		 */
		goToMyLocation() {
			uni.showToast({
				title: '定位功能待实现',
				icon: 'none'
			})
		},

		/**
		 * 触摸开始
		 */
		handleTouchStart(e) {
			// 记录触摸开始时间和位置
			this.touchStartTime = Date.now()
			this.isLongPressing = false

			// 获取触摸点坐标（clientX/clientY是相对于屏幕视口的坐标）
			const touch = e.touches[0] || e.changedTouches[0]
			this.touchStartPosition = {
				x: touch.clientX,
				y: touch.clientY
			}

			// 设置长按定时器
			this.longPressTimer = setTimeout(() => {
				this.isLongPressing = true
				this.triggerLongPress(this.touchStartPosition)
			}, LONG_PRESS_DURATION)
		},

		/**
		 * 触摸移动
		 */
		handleTouchMove(e) {
			// 如果触摸移动超过一定距离，取消长按
			const touch = e.touches[0] || e.changedTouches[0]
			const deltaX = Math.abs(touch.clientX - this.touchStartPosition.x)
			const deltaY = Math.abs(touch.clientY - this.touchStartPosition.y)

			// 移动超过10px就取消长按
			if (deltaX > 10 || deltaY > 10) {
				this.cancelLongPress()
			}
		},

		/**
		 * 触摸结束
		 */
		handleTouchEnd(e) {
			const touchDuration = Date.now() - this.touchStartTime

			// 如果触摸时长小于长按时长，取消长按
			if (touchDuration < LONG_PRESS_DURATION) {
				this.cancelLongPress()
			}

			// 清除定时器
			if (this.longPressTimer) {
				clearTimeout(this.longPressTimer)
				this.longPressTimer = null
			}
		},

		/**
		 * 触摸取消
		 */
		handleTouchCancel(e) {
			this.cancelLongPress()
		},

		/**
		 * 取消长按
		 */
		cancelLongPress() {
			this.isLongPressing = false
			if (this.longPressTimer) {
				clearTimeout(this.longPressTimer)
				this.longPressTimer = null
			}
		},

		/**
		 * 触发长按事件
		 */
		triggerLongPress(position) {
			console.log('触发长按事件，屏幕坐标:', position)

			// 检查登录状态
			const token = uni.getStorageSync('token')
			if (!token) {
				uni.showModal({
					title: '提示',
					content: '请先登录后再添加地点',
					confirmText: '去登录',
					success: (res) => {
						if (res.confirm) {
							uni.navigateTo({
								url: '/pages/login/login'
							})
						}
					}
				})
				return
			}

			// 震动反馈
			uni.vibrateShort()

			// 使用坐标转换工具将屏幕坐标转换为原始图片坐标
			const originalCoord = this.coordinateTransform.screenToOriginal(position.x, position.y)

			console.log('坐标转换详情:', {
				屏幕坐标: position,
				地图偏移: this.mapPosition,
				缩放比例: this.mapScale,
				原始图片坐标: originalCoord,
				变换矩阵: this.coordinateTransform.getMatrix()
			})

			this.longPressPosition = originalCoord
			this.addLocationForm = {
				name: '',
				coordinateX: originalCoord.x,
				coordinateY: originalCoord.y
			}

			// 创建临时标记点（用于预览位置）
			this.tempMarker = {
				coordinateX: originalCoord.x,
				coordinateY: originalCoord.y
			}

			// 显示添加地点表单
			this.showAddLocationForm = true
		},

		/**
		 * 关闭添加地点表单
		 */
		closeAddLocationForm() {
			this.showAddLocationForm = false
			this.addLocationForm = {
				name: '',
				coordinateX: 0,
				coordinateY: 0
			}
			// 移除临时标记点
			this.tempMarker = null
		},

		/**
		 * 提交新地点
		 */
		async submitNewLocation() {
			if (!this.addLocationForm.name) {
				uni.showToast({
					title: '请输入地点名称',
					icon: 'none'
				})
				return
			}

			this.isSubmitting = true
			try {
				const response = await locationAPI.createLocation({
					name: this.addLocationForm.name,
					coordinateX: this.addLocationForm.coordinateX,
					coordinateY: this.addLocationForm.coordinateY
				})

				if (response.success) {
					// 移除临时标记点
					this.tempMarker = null

					uni.showModal({
						title: '提交成功',
						content: '你的地点已提交审核,待管理员批准后将显示在地图上',
						showCancel: false,
						success: () => {
							this.closeAddLocationForm()
						}
					})
				}
			} catch (error) {
				console.error('添加地点失败:', error)
				utils.handleError(error, '添加地点失败')
			} finally {
				this.isSubmitting = false
			}
		}
	}
}
</script>

<style scoped>
/* 容器 */
.map-container {
	width: 100vw;
	height: 100vh;
	position: relative;
	overflow: hidden;
	background-color: #f5f5f5;
}

/* 地图区域 */
.map-area {
	width: 100%;
	height: 100%;
}

.map-view {
	width: 100%;
	height: 100%;
	position: relative;
	/* 裁剪超出的内容，因为 map-scale-wrapper 的布局尺寸会超出 */
	overflow: hidden;
}

.map-scale-wrapper {
	position: relative;
	width: 100%;
	transition: transform 0.2s ease;
}

.map-image {
	/* 强制图片尺寸匹配地图原始尺寸，确保坐标计算准确 */
	width: 4370px !important;
	height: 6142px !important;
	display: block;
}

/* 地点标记 */
.map-marker {
	position: absolute;
	transform-origin: center bottom;
	z-index: 10;
	cursor: pointer;
}

.marker-pin {
	width: 48rpx;
	height: 48rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	/* 移除背景色，因为使用图片 */
	filter: drop-shadow(0 4rpx 8rpx rgba(0, 0, 0, 0.2));
}

/* 临时标记点（长按预览） */
.temp-marker {
	z-index: 20;
	animation: fadeIn 0.3s ease;
}

.temp-pin {
	filter: drop-shadow(0 4rpx 12rpx rgba(251, 146, 60, 0.6)) !important;
	animation: pulse 1.5s ease-in-out infinite;
}

/* 临时标记的图标颜色调整 */
.temp-pin .marker-icon {
	/* 橙色滤镜效果 */
	filter: brightness(1.1) hue-rotate(20deg) saturate(1.3);
}

.temp-label {
	position: absolute;
	top: -40rpx;
	left: 50%;
	transform: translateX(-50%);
	background: rgba(251, 146, 60, 0.95);
	color: #ffffff;
	font-size: 22rpx;
	font-weight: 500;
	padding: 6rpx 12rpx;
	border-radius: 8rpx;
	white-space: nowrap;
	box-shadow: 0 2rpx 8rpx rgba(251, 146, 60, 0.3);
}

@keyframes fadeIn {
	from {
		opacity: 0;
		transform: scale(0.8);
	}
	to {
		opacity: 1;
		transform: scale(1);
	}
}

@keyframes pulse {
	0%, 100% {
		transform: scale(1);
		opacity: 1;
	}
	50% {
		transform: scale(1.15);
		opacity: 0.85;
	}
}

.marker-icon {
	width: 100%;
	height: 100%;
	display: block;
}

.marker-badge {
	position: absolute;
	top: -12rpx;
	right: -12rpx;
	background: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 100%);
	color: #ffffff;
	font-size: 20rpx;
	font-weight: bold;
	padding: 4rpx 8rpx;
	border-radius: 12rpx;
	box-shadow: 0 2rpx 8rpx rgba(238, 90, 111, 0.4);
	z-index: 1;
}

/* 地点名称标签 */
.marker-label {
	position: absolute;
	top: 52rpx; /* 在图标下方,根据图标高度48rpx + 4rpx间距 */
	left: 50%;
	transform: translateX(-50%);
	background: rgba(255, 255, 255, 0.95);
	color: #1f2937;
	font-size: 20rpx;
	font-weight: 500;
	padding: 4rpx 8rpx;
	border-radius: 6rpx;
	white-space: nowrap;
	box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.15);
	border: 1rpx solid rgba(34, 197, 94, 0.2);
	max-width: 120rpx; /* 限制最大宽度 */
	overflow: hidden;
	text-overflow: ellipsis;
	pointer-events: none; /* 避免阻挡点击事件 */
}

/* 控制按钮 */
.controls {
	position: absolute;
	top: 20rpx;
	right: 20rpx;
	z-index: 100;
	display: flex;
	flex-direction: column;
	gap: 20rpx;
}

.zoom-controls {
	display: flex;
	flex-direction: column;
	gap: 8rpx;
	background: rgba(255, 255, 255, 0.95);
	border-radius: 16rpx;
	padding: 8rpx;
	box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
}

.control-btn {
	width: 80rpx;
	height: 80rpx;
	background: #ffffff;
	border-radius: 12rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: all 0.2s ease;
	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
}

.control-btn:active {
	background: #f5f5f5;
	transform: scale(0.95);
}

.control-icon {
	font-size: 48rpx;
	color: #22c55e;
	font-weight: bold;
}

.my-location-btn {
	width: 96rpx;
	height: 96rpx;
	background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 4rpx 16rpx rgba(34, 197, 94, 0.4);
	cursor: pointer;
}

.my-location-btn .control-icon {
	color: #ffffff;
	font-size: 52rpx;
}

/* 加载提示 */
.loading-overlay {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.3);
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 1000;
}

.loading-content {
	background: #ffffff;
	padding: 60rpx 80rpx;
	border-radius: 24rpx;
	display: flex;
	flex-direction: column;
	align-items: center;
	box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.2);
}

.loading-spinner {
	width: 60rpx;
	height: 60rpx;
	border: 6rpx solid #e5e7eb;
	border-top-color: #22c55e;
	border-radius: 50%;
	animation: spin 1s linear infinite;
	margin-bottom: 24rpx;
}

@keyframes spin {
	to {
		transform: rotate(360deg);
	}
}

.loading-text {
	font-size: 28rpx;
	color: #6b7280;
}

/* 信息窗口 */
.info-window {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	background: #ffffff;
	border-radius: 32rpx 32rpx 0 0;
	box-shadow: 0 -8rpx 32rpx rgba(0, 0, 0, 0.1);
	z-index: 500;
	transform: translateY(100%);
	transition: transform 0.3s ease;
	max-height: 50vh;
}

.info-window.show {
	transform: translateY(0);
}

.info-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 32rpx 40rpx;
	border-bottom: 2rpx solid #e5e7eb;
}

.info-title {
	font-size: 36rpx;
	font-weight: bold;
	color: #1f2937;
}

.info-close {
	width: 60rpx;
	height: 60rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 40rpx;
	color: #9ca3af;
	cursor: pointer;
}

.info-body {
	padding: 32rpx 40rpx;
}

.info-rating {
	text-align: center;
	margin-bottom: 32rpx;
}

.rating-value {
	display: block;
	font-size: 72rpx;
	font-weight: bold;
	color: #22c55e;
	margin-bottom: 12rpx;
}

.rating-label {
	display: block;
	font-size: 28rpx;
	color: #6b7280;
	margin-bottom: 8rpx;
}

.rating-count {
	display: block;
	font-size: 24rpx;
	color: #9ca3af;
}

.info-actions {
	display: flex;
	gap: 24rpx;
}

.action-btn {
	flex: 1;
	height: 88rpx;
	border-radius: 16rpx;
	font-size: 32rpx;
	font-weight: 500;
	border: none;
}

.action-btn.primary {
	background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);
	color: #ffffff;
	box-shadow: 0 4rpx 16rpx rgba(34, 197, 94, 0.3);
}

.action-btn.secondary {
	background: #ffffff;
	color: #22c55e;
	border: 2rpx solid #22c55e;
}

.action-btn:active {
	opacity: 0.8;
	transform: scale(0.98);
}

/* 弹窗样式 */
.modal-overlay {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.5);
	z-index: 2000;
	display: flex;
	align-items: flex-end;
	justify-content: center;
}

.modal-content {
	background: #ffffff;
	border-radius: 32rpx 32rpx 0 0;
	width: 100%;
	max-height: 80vh;
	display: flex;
	flex-direction: column;
	animation: slideUp 0.3s ease;
}

@keyframes slideUp {
	from {
		transform: translateY(100%);
	}
	to {
		transform: translateY(0);
	}
}

.modal-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 32rpx 40rpx;
	border-bottom: 2rpx solid #e5e7eb;
}

.modal-title {
	font-size: 36rpx;
	font-weight: bold;
	color: #1f2937;
}

.modal-close {
	width: 60rpx;
	height: 60rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 40rpx;
	color: #9ca3af;
	cursor: pointer;
}

.form-body {
	padding: 40rpx;
	overflow-y: auto;
}

.form-item {
	margin-bottom: 32rpx;
}

.form-label {
	display: block;
	font-size: 28rpx;
	color: #374151;
	margin-bottom: 16rpx;
	font-weight: 500;
}

.form-input {
	width: 100%;
	height: 88rpx;
	padding: 0 24rpx;
	background: #f9fafb;
	border: 2rpx solid #e5e7eb;
	border-radius: 12rpx;
	font-size: 28rpx;
	color: #1f2937;
}

.form-input:focus {
	border-color: #22c55e;
	background: #ffffff;
}

.coordinate-text {
	display: block;
	font-size: 28rpx;
	color: #1f2937;
	padding: 24rpx;
	background: #f9fafb;
	border-radius: 12rpx;
	margin-bottom: 8rpx;
	font-family: monospace;
}

.coordinate-hint {
	display: block;
	font-size: 24rpx;
	color: #9ca3af;
}

.submit-btn {
	width: 100%;
	height: 88rpx;
	background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);
	color: #ffffff;
	font-size: 32rpx;
	font-weight: 500;
	border-radius: 16rpx;
	border: none;
	margin-top: 16rpx;
	box-shadow: 0 4rpx 16rpx rgba(34, 197, 94, 0.3);
}

.submit-btn[disabled] {
	opacity: 0.5;
}

.submit-btn:active:not([disabled]) {
	opacity: 0.8;
	transform: scale(0.98);
}

.form-hint {
	display: flex;
	align-items: flex-start;
	gap: 12rpx;
	margin-top: 24rpx;
	padding: 24rpx;
	background: #eff6ff;
	border-radius: 12rpx;
	border-left: 4rpx solid #3b82f6;
}

.hint-icon {
	font-size: 28rpx;
	flex-shrink: 0;
}

.hint-text {
	font-size: 24rpx;
	color: #3b82f6;
	line-height: 1.6;
}
</style>
